package tools.jackson.databind.misc;

import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

import tools.jackson.databind.MapperFeature;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.json.JsonMapper;
import tools.jackson.databind.testutil.DatabindTestUtil;

import static org.junit.jupiter.api.Assertions.assertEquals;

// [databind#5292] Need support for creators `MapperFeature.FIX_FIELD_NAME_UPPER_CASE_PREFIX`
public class IPhoneStyleProperty5292Test
    extends DatabindTestUtil
{
    static class AppleSingleNonTarget {
        private final String name;

        public AppleSingleNonTarget(@ImplicitName("name") String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }

    static class AppleSingleIsTarget {
        private final String iPhone;

        @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
        public AppleSingleIsTarget(@ImplicitName("iPhone") String iPhone) {
            this.iPhone = iPhone;
        }

        public String getIPhone() {
            return iPhone;
        }
    }

    // Creator order should be used but just in case, define explicit order
    @JsonPropertyOrder({ "iPhone", "name" })
    static class AppleDouble {
        private final String _iphone;
        private final String name;

        public AppleDouble(@ImplicitName("iPhone") String iPhone,
                @ImplicitName("name") String name) {
            this._iphone = iPhone;
            this.name = name;
        }

        public String getIPhone() {
            return _iphone;
        }

        public String getName() {
            return name;
        }
    }

    private final ObjectMapper MAPPER = JsonMapper.builder()
        .annotationIntrospector(new ImplicitNameIntrospector())
        .enable(MapperFeature.FIX_FIELD_NAME_UPPER_CASE_PREFIX)
        .build();

    @Test
    public void testDeserDouble() throws Exception
    {
        AppleDouble apple = new AppleDouble("iPhone 15", "Jay");
        String json = MAPPER.writeValueAsString(apple);
        assertEquals("{\"iPhone\":\"iPhone 15\",\"name\":\"Jay\"}", json);

        AppleDouble result = MAPPER.readValue(json, AppleDouble.class); // Error thrown

        assertEquals("Jay", result.getName());
        assertEquals("iPhone 15", result.getIPhone());
    }


    @Test
    public void testSingleArgCase() throws Exception
    {
        AppleSingleIsTarget apple = new AppleSingleIsTarget("iPhone 15");
        String json = MAPPER.writeValueAsString(apple);
        assertEquals("{\"iPhone\":\"iPhone 15\"}", json);

        AppleSingleIsTarget result = MAPPER.readValue(json, AppleSingleIsTarget.class);
        assertEquals("iPhone 15", result.getIPhone());
    }

    // Just for comparison
    @Test
    public void testHappyCaseSingleArgString() throws Exception
    {
        AppleSingleNonTarget apple = new AppleSingleNonTarget("Jay");
        String json = MAPPER.writeValueAsString(apple);
        assertEquals("{\"name\":\"Jay\"}", json);

        AppleSingleNonTarget result = MAPPER.readValue(json, AppleSingleNonTarget.class);
        assertEquals("Jay", result.getName());
    }
}
